using System;
using PingPong.GameEngine.Components;

namespace PingPong.GameEngine
{

	public class GameCondition
	{

		#region Members

		/// <summary>
		/// The expression.
		/// </summary>
		private Lazy<string> expression;
		/// <summary>
		/// The type of the expression boolean.
		/// </summary>
		private Lazy<ExpressionBooleanType> expressionBooleanType;

		#endregion

		#region Properties

		/// <summary>
		/// Gets the expression.
		/// </summary>
		/// <value>
		/// The expression.
		/// </value>
		public string Expression
		{
			get
			{
				return this.expression.Value;
			}
		}

		/// <summary>
		/// Gets the type of the expression boolean.
		/// </summary>
		/// <value>The type of the expression boolean.</value>
		public ExpressionBooleanType ExpressionBooleanType
		{
			get
			{
				return this.expressionBooleanType.Value;
			}
		}

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="PingPong.GameEngine.GameCondition"/> class.
		/// </summary>
		public GameCondition()
		{
			this.expression = new Lazy<string>(() => string.Empty);
			this.expressionBooleanType = new Lazy<ExpressionBooleanType>(() => ExpressionBooleanType.None);
		}

		#endregion

		#region Methods

		/// <summary>
		/// Evaluate this instance.
		/// </summary>
		public bool Evaluate()
		{
			Engine.ExpressionParser.Interpret(this.Expression);
			return Engine.ExpressionParser.Output.Equals(
				bool.TrueString,
				StringComparison.OrdinalIgnoreCase
			);
		}

		/// <summary>
		/// Sets the expression.
		/// </summary>
		/// <returns>The expression.</returns>
		/// <param name="expression">Expression.</param>
		public GameCondition SetExpression(string expression)
		{
			this.expression = new Lazy<string>(() => expression);
			return this;
		}

		/// <summary>
		/// Sets the expression.
		/// </summary>
		/// <returns>The expression.</returns>
		/// <param name="expression">Expression.</param>
		/// <param name="expressionBooleanType">Expression boolean type.</param>
		public GameCondition SetExpression(string expression, ExpressionBooleanType expressionBooleanType)
		{
			this.expression = new Lazy<string>(() => expression);
			this.expressionBooleanType = new Lazy<ExpressionBooleanType>(() => expressionBooleanType);
			return this;
		}

		#endregion

	}
}

